package imp

import (
	sqlc "bgs/db/sqlc"
	orderGrpc "bgs/grpc/gen/service/order"
	"bgs/grpc/gen/shared/message"
	"bgs/grpc/imp/enums"
	"bgs/service/model"
	"context"
	"encoding/json"
	"strconv"
)

/****************************************************************************************/
/*                               orderOfS entity of helper                              */
/****************************************************************************************/

func transformOrderItemForSEntityToPb(o sqlc.Order) *orderGrpc.OrderItemForSEntity {
	orderExtInfo := &model.OrderExtInfo{}
	json.Unmarshal(o.ExtInfo, orderExtInfo)
	var ownerName, ownerPic, ownerTel string
	if o.StoreID.Valid {
		ownerName = orderExtInfo.StoreName
		ownerPic = orderExtInfo.StorePic
		ownerTel = orderExtInfo.StoreTel
	} else {
		ownerName = orderExtInfo.BrandName
		ownerPic = orderExtInfo.BrandPic
		ownerTel = orderExtInfo.BrandTel
	}

	return &orderGrpc.OrderItemForSEntity{
		Id:                o.ID,
		Ordered:           sqlc.GoTimeToPBTimestamp(o.Ordered),
		SerialNumber:      o.SerialNumber,
		BrandId:           o.BrandID,
		StoreId:           o.StoreID.Int64,
		DistributorId:     o.DistributorID.Int64,
		DistributorUserId: o.DistributorUserID.Int64,
		ActivityId:        o.ActivityID,
		SpokesmanId:       o.SpokesmanID.Int64,
		SpokesmanUserId:   o.SpokesmanUserID.Int64,
		OrderType:         o.OrderType,
		OrderStatus:       o.OrderStatus,
		DeliveryMode:      o.DeliveryMode,
		Amount:            o.Amount,
		OrderDetails:      mapOrderDetailEntityToPb(orderExtInfo.Details, transformOrderDetailEntityToPb),
		OwnerName:         ownerName,
		OwnerPic:          ownerPic,
		OwnerTel:          ownerTel,
		ActivityName:      orderExtInfo.ActivityName,
		ActivityTel:       orderExtInfo.ActivityTel,
		BuyerNickName:     orderExtInfo.BuyerNickName,
		BuyerPic:          orderExtInfo.BuyerPic,
	}
}

func mapOrderItemForSEntityToPb(list []sqlc.Order, f func(sqlc.Order) *orderGrpc.OrderItemForSEntity) []*orderGrpc.OrderItemForSEntity {
	r := make([]*orderGrpc.OrderItemForSEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                               orderOfS entity of query                               */
/****************************************************************************************/

// ListOrderItemsForS 分页获取多个订单(视角S)
func (s *OrderAPIService) ListOrderItemsForS(ctx context.Context, req *orderGrpc.ListOrderItemsForSRequest) (res *orderGrpc.ListOrderItemsForSResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("orderOfS->ListOrderItemsForS:%v", req)

	res = &orderGrpc.ListOrderItemsForSResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q
	ts := sqlc.PBTimestampToGoTime(req.Ts)
	userID := req.UserId
	isAll := req.IsAll
	orderStatuses := req.OrderStatuses
	searchTerm := req.SearchTerm
	if !(searchTerm == "" || searchTerm == string(enums.SearchTermActivity) || searchTerm == string(enums.SearchTermBrand)) {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     "searchTerm不支持",
		}
		return
	}

	var searchValue int64
	if req.SearchValue != "" {
		searchValue, err = strconv.ParseInt(req.SearchValue, 10, 64)
		if err != nil {
			res.OpRet = &message.OperationResult{
				Success: false,
				Code:    400,
				Msg:     err.Error(),
			}
			return
		}
	}

	total, err := q.CountOrdersAsSpokesmanSearcher(ctx, sqlc.CountOrdersAsSpokesmanSearcherParams{
		Created:         ts,
		SpokesmanUserID: sqlc.NInt64FromInt64(userID),
		IsAll:           isAll,
		OrderStatuses:   orderStatuses,
		SearchTerm:      searchTerm,
		SearchValue:     searchValue,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	if total == 0 {
		// 不用继续调用listfunc
		return
	}

	orders, err := q.ListOrdersAsSpokesmanSearcher(ctx, sqlc.ListOrdersAsSpokesmanSearcherParams{
		Limit:           req.Limit,
		Offset:          req.Offset,
		Created:         ts,
		SpokesmanUserID: sqlc.NInt64FromInt64(userID),
		IsAll:           isAll,
		OrderStatuses:   orderStatuses,
		SearchTerm:      searchTerm,
		SearchValue:     searchValue,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.OrderItemsForS = mapOrderItemForSEntityToPb(orders, transformOrderItemForSEntityToPb)
	return
}
